package org.dreamwork.jasmine2.web.controls.chart.servlet;

import org.dreamwork.jasmine2.util.StringConverter;
import org.dreamwork.jasmine2.web.controls.chart.ChartContext;
import org.dreamwork.jasmine2.web.controls.chart.IChartDataProvider;
import org.dreamwork.jasmine2.web.controls.chart.format.IChartDataFormat;
import org.dreamwork.jasmine2.web.controls.chart.format.LineDataFormat;
import org.dreamwork.jasmine2.web.controls.chart.format.PieDataFormat;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2010-5-12
 * Time: 10:36:54
 */
public class FlashChartServlet extends HttpServlet {
    private static final String CONTENT_TYPE = "text/xml;charset=UTF-8";

    @Override
    @SuppressWarnings ("unchecked")
    protected void service (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String provider = request.getParameter ("p");
        String valueField = request.getParameter ("v");
        String textField = request.getParameter ("t");
        String chartType = request.getParameter ("r");
        String url = request.getParameter ("u");

        ServletContext application = getServletContext ();
        Map<String, String> pool = (Map<String, String>) application.getAttribute ("org.dreamwork.chart.pool");
        provider = pool.get (provider);

        if (StringConverter.isEmpty (provider) || StringConverter.isEmpty (valueField) || StringConverter.isEmpty (textField))
            throw new ServletException ("");

        ChartContext context = new ChartContext ();
        context.addParameter ("textField", textField);
        context.addParameter ("valueField", valueField);
        if (!StringConverter.isEmpty (url))
            context.addParameter ("url", url);
        for (Enumeration e = request.getParameterNames (); e.hasMoreElements (); ) {
            String key = (String) e.nextElement ();
            if ("p".equalsIgnoreCase (key) ||
                "v".equalsIgnoreCase (key) ||
                "t".equalsIgnoreCase (key) ||
                "c".equalsIgnoreCase (key) ||
                "r".equalsIgnoreCase (key) ||
                "u".equalsIgnoreCase (key))
                continue;
            String[] values = request.getParameterValues (key);
            if (values.length == 1) context.addParameter (key, values [0]);
            else context.addParameter (key, values);
        }

        try {
            Class clazz = Class.forName (provider);
            IChartDataProvider p = (IChartDataProvider) clazz.newInstance ();
            List<?> data = p.getData (context);
            response.setContentType (CONTENT_TYPE);
            StringBuilder builder = new StringBuilder ();
            if ("pie".equalsIgnoreCase (chartType)) {
                String colorField = request.getParameter ("c");
                if (!StringConverter.isEmpty (colorField))
                    context.addParameter ("colorField", colorField);
                buildPieData (data, builder, context);
            } else if ("line".equalsIgnoreCase (chartType) || "column".equalsIgnoreCase (chartType)) {
                String categoryField = request.getParameter ("c");
                String categoryColorField = request.getParameter ("cc");
                context.addParameter ("categoryField", categoryField);
                if (!StringConverter.isEmpty (categoryColorField))
                    context.addParameter ("categoryColorField", categoryColorField);
                buildLineData (data, builder, context);
            }
            response.getWriter ().write (builder.toString ());
            response.flushBuffer ();
        } catch (Exception e) {
            throw new ServletException (e);
        }
    }

    private void buildPieData (List<?> data, StringBuilder builder, ChartContext context) {
        IChartDataFormat cdf = new PieDataFormat ();
        builder.append (cdf.format (data, context));
    }

    private void buildLineData (List<?> data, StringBuilder builder, ChartContext context) {
        IChartDataFormat cdf = new LineDataFormat ();
        builder.append (cdf.format (data, context));
    }
}